package 晚间作业0324;

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Doc16 {

    /**
     * 1. 实例化两个线程，同时对一个数字进行操作。一个线程对这个数字进行加1，另外一个线程对这个数字进行减
     * 一。输出每一次的操作之后的这个数字的值。
     */
    public static class Q01 {
        public static void main(String[] args) {
            AtomicInt atomicInt = new AtomicInt(0);
            Runnable addRun = () -> {
                for (int i = 0; i < 10; i++) {
                    System.out.println("加线程：" + atomicInt.addAndGet(1));
                }
            };
            Runnable subRun = () -> {
                for (int i = 0; i < 10; i++) {
                    System.out.println("减线程：" + atomicInt.addAndGet(-1));
                }
            };

            new Thread(addRun).start();
            new Thread(subRun).start();
        }

        public static class AtomicInt {
            private int value;

            public AtomicInt(int initialize) {
                this.value = initialize;
            }

            public synchronized int addAndGet(int add) {
                return value += add;
            }
        }
    }

    /**
     * 2. 有五个人同时过一个独木桥，一个独木桥同时只能允许一个人通过。每一个人通过独木桥的时间是随机在
     * [5,10] 秒，输出这个独木桥上每一个人的通过详情，例如：张三开始过独木桥了... 张三通过独木桥了!
     */
    public static class Q02 {
        public static void main(String[] args) {
            Person zhangsan = new Person("张三");
            Person lisi = new Person("李四");
            Person wangwu = new Person("王五");
            Person zhaoliu = new Person("赵六");
            Person zhouqi = new Person("周七");
            Bridge bridge = new Bridge();

            new Thread(() -> zhangsan.cross(bridge)).start();
            new Thread(() -> lisi.cross(bridge)).start();
            new Thread(() -> wangwu.cross(bridge)).start();
            new Thread(() -> zhaoliu.cross(bridge)).start();
            new Thread(() -> zhouqi.cross(bridge)).start();
        }

        public static class Person {
            private String name;

            public Person(String name) {
                this.name = name;
            }

            public void cross(Bridge bridge) {
                bridge.transport(name);
            }
        }

        public static class Bridge {
            public static final Random RANDOM = new Random();

            public synchronized void transport(String name) {
                System.out.println(name + "开始过独木桥了");
                int second = RANDOM.nextInt(5) + 5;
                try {
                    Thread.sleep(second * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(name + "通过独木桥了, 耗时：" + second + "s");
            }
        }
    }

    /**
     * 6.需求说明
     * 定义一个线程A，输出1 〜 10之间的整数， 定义一个线程B，逆序输出1 〜 10之间的整数，要求线程A和线程B交替输出
     */
    public static class Q06 {
        public static void main(String[] args) {
            Lock lock = new ReentrantLock();
            Condition condition = lock.newCondition();

            new Thread(() -> {
                lock.lock();
                for (int i = 1; i <= 10; i++) {
                    System.out.println("A: " + i);
                    condition.signal();
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                condition.signal();
                lock.unlock();
            }).start();

            new Thread(() -> {
                lock.lock();
                for (int i = 10; i > 0; i--) {
                    System.out.println("B: " + i);
                    condition.signal();
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lock.unlock();
            }).start();
        }
    }
}
